package com.rustic.server.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.xy.commons.exception.JzRuntimeException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rustic.server.dao.UserBrowseLinkDao;
import com.rustic.server.enums.LinkType;
import com.rustic.server.po.UserBrowseLink;
import com.rustic.server.query.UserBrowseLinkAdminListQuery;
import com.rustic.server.service.CommentService;
import com.rustic.server.service.UserBrowseLinkService;
import com.rustic.server.vo.list.UserBrowseLinkAdminListVO;
import com.rustic.server.vo.list.UserBrowseLinkWebListVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * UserBrowseLink对应的服务类实现
 *
 * @author auto
 */

@Service
public class UserBrowseLinkServiceImpl extends ServiceImpl<UserBrowseLinkDao, UserBrowseLink> implements UserBrowseLinkService {

    @Autowired
    private CommentService commentService;

    @Override
    public List<UserBrowseLink> listByIdIn(List<Integer> idList) {
        if (CollUtil.isEmpty(idList)) {
            return new ArrayList<>();
        }
        return this.listByIds(idList);
    }

    @Override
    public Map<Integer, UserBrowseLink> mapByIdIn(List<Integer> idList) {
        List<UserBrowseLink> userBrowseLinkList = this.listByIdIn(idList);
        return userBrowseLinkList.stream().collect(Collectors.toMap(UserBrowseLink::getId, b -> b));
    }

    @Override
    public LambdaQueryWrapper<UserBrowseLink> toAdminListWrapper(UserBrowseLinkAdminListQuery query) {
        LambdaQueryWrapper<UserBrowseLink> queryWrapper = new LambdaQueryWrapper<>();
        //FIXME 根据需要修改搜索条件
        queryWrapper.eq(query.getTargetId() > 0, UserBrowseLink::getTargetId, query.getTargetId());
        queryWrapper.eq(query.getUserId() > 0, UserBrowseLink::getUserId, query.getUserId());
        queryWrapper.eq(query.getType() > 0, UserBrowseLink::getType, query.getType());
        queryWrapper.gt(query.getStartCreateTime() != null, UserBrowseLink::getCreateTime, query.getStartCreateTime());
        queryWrapper.lt(query.getEndCreateTime() != null, UserBrowseLink::getCreateTime, query.getEndCreateTime());
        return queryWrapper;
    }

    @Override
    public List<UserBrowseLinkAdminListVO> toAdminListVo(List<UserBrowseLink> userBrowseLinkList) {
        List<UserBrowseLinkAdminListVO> results = new ArrayList<>();
        for (UserBrowseLink userBrowseLink : userBrowseLinkList) {
            UserBrowseLinkAdminListVO userBrowseLinkAdminListVO = new UserBrowseLinkAdminListVO(userBrowseLink);
            results.add(userBrowseLinkAdminListVO);
        }
        return results;
    }

    @Override
    public List<UserBrowseLinkWebListVO> toWebListVo(List<UserBrowseLink> userBrowseLinkList) {
        List<UserBrowseLinkWebListVO> results = new ArrayList<>();
        for (UserBrowseLink userBrowseLink : userBrowseLinkList) {
            UserBrowseLinkWebListVO userBrowseLinkWebListVO = new UserBrowseLinkWebListVO(userBrowseLink);
            results.add(userBrowseLinkWebListVO);
        }
        return results;
    }

    @Override
    public Map<Integer, Long> mapByTargetIdAndType(List<Integer> targetIdList, LinkType type) {
        if (CollUtil.isEmpty(targetIdList)) {
            return new HashMap<>();
        }
        List<UserBrowseLink> list = this.list(new LambdaQueryWrapper<UserBrowseLink>()
                .eq(UserBrowseLink::getType, type.getValue())
                .in(UserBrowseLink::getTargetId, targetIdList));
        // 使用流来转换和收集结果
        return list.stream()
                .collect(Collectors.groupingBy(
                        UserBrowseLink::getTargetId, // 分组依据：targetId
                        Collectors.counting()       // 收集器：计数
                ));
    }

    @Override
    public Long getByTargetAndType(int targetId, LinkType type) {
        return this.count(new LambdaQueryWrapper<UserBrowseLink>()
                .eq(UserBrowseLink::getTargetId, targetId)
                .eq(UserBrowseLink::getType, type.getValue()));
    }

    @Override
    public void addBrowse(int userId, int targetId, int type) {
        // 校验是否有浏览过
        if (userId > 0 ) {
            UserBrowseLink browseLink = this.getByUserTargetAndType(userId, targetId, type);
            if (browseLink != null) {
                browseLink.setCreateTime(new Date());
                this.updateById(browseLink);
                return;
            }
        }
        try {
            int rusticId = commentService.addInteractionDataCheck(targetId, type);
            UserBrowseLink userBrowseLink = new UserBrowseLink();
            userBrowseLink.setUserId(userId);
            userBrowseLink.setRusticId(rusticId);
            userBrowseLink.setType(type);
            userBrowseLink.setTargetId(targetId);
            this.save(userBrowseLink);
        } catch (JzRuntimeException ignored) {
        } catch (Exception e) {
            // 其他非JzRuntimeException的异常继续抛出
            log.error("浏览记录添加的异常=>{}", e);
            throw e;
        }
    }

    @Override
    public UserBrowseLink getByUserTargetAndType(int userId, int targetId, int type) {
        return this.getOne(new LambdaQueryWrapper<UserBrowseLink>()
                .eq(UserBrowseLink::getUserId, userId)
                .eq(UserBrowseLink::getTargetId, targetId)
                .eq(UserBrowseLink::getType, type));
    }
}
